Novelang

The electronic document generator

Detailed syntax

Now let’s discover all decorations supported by a Novella.

Along with their syntax is given the XML element names usable in a XSL stylesheet. Names may seem weird at the first glance. A block inside two pairs of solidus // is called n:block-inside-solidus-pairs. Why not calling it simply “italics”? First, keep in mind that those XML names only appear inside custom stylesheets so you may not care about them at all. Novelang transforms the source document in an abstract tree before rendering it through a stylesheet. If you create your own stylesheet you can process a block inside // like a footnote in super-bold or whatever, then “italics” would be quite confusing. So XML element names don’t try to carry assumptions about the usage of the element. It just describes the originating decoration.

Paragraph, regular

XML element: n:paragraph-regular

A regular paragraph is made of contiguous lines of text (two consecutive line breaks cannot occur inside a paragraph). A paragraph may contain words, punctuation signs, external links, list items and blocks.

With Novelang default stylesheet, such text is rendered as normal text:

First
paragraph.

Second paragraph.

Levels

XML elements: n:level, n:level-title

Levels are delimited with a simple syntax, using a separator = telling about the depth of the level. A Novella contains up to three levels, including level 0 which is the default.

Considering a Novella like this:

Text at depth 0.

== Depth 1

Introductory text.

=== Depth 2

Blah blah blah.

=== Depth 2

Blah.

== Depth 1 again

=== Depth 2

...

The level structure of the Novella looks like this:

+ n:novella
  + n:paragraph-regular "Text at depth 0"
  + n:level
  | + n:level-title "Depth 1"
  | + n:paragraph-regular "Introductory text."
  | + n:level
  | | + n:level-title "Depth 2"
  | | + n:paragraph-regular "Blah blah blah."
  | + n:level
  |   + n:level-title "Depth 2"
  |   + n:paragraph-regular "Blah."
  + n:level
    + n:level-title "Depth 1 again"
    + n:level
      + n:level-title "Depth 2"
      + n:paragraph-regular "..."

As explained later in this document, the depth of levels may be changed (increased) at Opus level. This is useful for creating documents which have great depth, while keeping edited content with at reasonable depth.

Inside a Novella, it’s incorrect to declare a first level with a greater depth than following one. The case below will cause an error:

== Depth 2, incorrect

=== Depth 1

Block inside solidus pairs

XML element: n:block-inside-solidus-pairs

Two pairs of solidus // may enclose a block of text.

With Novelang default stylesheet, such text is rendered as italics:

There are //italics//.

Block inside asterisk pairs

XML element: n:block-inside-asterisk-pairs

Two pairs of asterisk ** may enclose a block of text.

With Novelang default stylesheet, such text is rendered as bold:

This is **bold**.

Block inside double quotes

XML element: n:block-inside-double-quotes

Two double quotes " may enclose a block of text.

With Novelang default stylesheet, such text is rendered inside double quotes (the character may vary depending on the language):

There are "double quotes".

Block inside square brackets

XML element: n:block-inside-square-brackets

Two pairs of square brackets [ and ] may enclose a block of text.

With Novelang default stylesheet, such text is rendered inside square brackets:

There are [square brackets].

Block inside parenthesis

XML element: n:block-inside-parenthesis

Two pairs of square brackets ( and ) may enclose a block of text.

With Novelang default stylesheet, such text is rendered inside parenthesis:

There are (parenthesis).

Block inside hyphen pairs

XML elements: n:block-inside-hyphen-pairs, n:block-inside-two-hyphens-then-hyphen-low-line

Two pairs of hyphen minus -- may enclose a block of text.

There is an alternative where the ending delimiter is an hyphen then a low line _.

With Novelang default stylesheet, such text is rendered inside a pair of en dash characters (or em dash depending on language). This creates an interpolated clause. With the ending low line, there is no visible ending.

See -- interpolated clause -- here.
See -- no visible end -_.

Block of literal inside grave accents

XML element: n:block-of-literal-inside-grave-accents

Two grave accents ` may enclose a block of text containing characters which are not allowed otherwise (because they serve other Novelang grammar’s purpose).

With Novelang default stylesheet, such text is rendered as normal text:

Almost `4ny- ch@rac7er 0.0.0 "'&#^> / *`

Spaces are handled in a special manner:

  • Leading and trailing spaces are trimmed.
  • Consecutive spaces between two characters are collapsed into one single space.
  • Spaces are replaced by no-break spaces.

With the low line character _ figuring a no-break space, here is a sample of space replacement:

`  foo   bar ` becomes `foo_bar`

Block of literal inside grave accent pairs

XML element: n:block-of-literal-inside-grave-accent-pairs

Two pairs of grave accents `` may enclose a block of text containing characters which are not allowed otherwise (because they serve other Novelang grammar’s purpose).

With Novelang default stylesheet, such text is rendered as monospaced text:

Almost ``4ny- ch@rac7er 0.0.0 "'&#^> / *``

Spaces are handled the same way as with block of literal inside grave accents.

Block after tilde

XML elements: n:block-after-tilde, n:subblock

A tilde character ~ may prefix a block of text containing no space nor line break. Inside the same block there can be other tilde characters.

Considering this source document:

~one(single)~block!

The internal structure looks like this:

+ n:block-after-tilde
  + n:subblock
  | + "one"
  | + n:block-inside-parenthesis
  |   + "single"
  + n:subblock
    + "block"
    + n:punctuation-sign "!"

Subblock may contain:

  • Plain words.
  • Punctuation signs.
  • Block inside grave accents.
  • Block inside grave accent pairs.
  • Block inside parenthesis.
  • Block inside solidus pairs.

When inside block inside solidus pairs, a whitespace must follow the block after tilde:

//~(un)ambiguous //

With Novelang default stylesheet, the subblocks are separated with a zero-width space. This is fine for overriding whitespace addition for typographic effect(s).

Paragraphs inside angled bracket pairs

XML element: n:paragraphs-inside-angled-bracket-pairs

Two lower-than signs << and two greater-than signs >> may enclose one paragraph or more. The angled bracket delimiting the paragraphs take place on the first column of the line, and there must be no other character on the same line.

Whith Novelang default stylesheet, such text is rendered as quoted paragraphs:

<<
First paragraph.

Second paragraph.
>>

List with triple hyphen

XML elements: n:list-with-triple-hyphen, n:paragraph-as-list-item

A triple hyphen --- may start a paragraph, which becomes a list item. The triple hyphen must take place on the first column of the line. The paragraph as a list item follows the same rules as a regular paragraph.

With Novelang default stylesheet, such a paragraph is rendered as a list item, preceded by an em dash character:

--- First list item.

--- Second list item.

As XML element, the paragraph itself is a n:paragraph-as-list-item, while the sequence of items gets wrapped into a n:list-with-triple-hyphen element.

List with double hyphen and number sign

XML elements: n:list-with-double-hyphen-and-number-sign, n:paragraph-as-list-item

A double hyphen and a plus sign --# may start a paragraph, which becomes a list item. They must take place on the first column of the line. The paragraph as a list item follows the same rules as a regular paragraph.

With Novelang default stylesheet, such a paragraph is rendered as a numbered list item:

--# First list item.

--# Second list item.

As XML element, the paragraph itself is a n:paragraph-as-list-item, while the sequence of items gets wrapped into a n:list-with-double-hyphen-and-number-sign element.

Embedded list

XML elements: n:embedded-list-with-hyphen, n:embedded-list-with-number-sign, n:embedded-list-item

Inside a paragraph, a single hyphen - or a number sign # declares a list item. A list item is made of one single line (a line break would be interpreted as the end of item). An embedded list may declare subitems, with a greater indentation than containing item. All items of the same list have the same leading character (the behavior when mixing them remains undefined at this time).

With Novelang default stylesheet, the embedded list is rendered as a list, supporting nested elements (up to 3 levels with PDF, unlimited levels with HTML):

One embedded list:
- Item one.
- Item two.
  - Item two one.
  - Item two two.
- Item three.
And another one, in the same paragraph
# Item one.
# Item two.
  # Item two one.
End of paragraph.

As XML elements, the list is wrapped in a n:embedded-list-with-hyphen or n:embedded-list-with-number-sign, while each item gets wrapped into a n:embedded-list-item element. Sublists are wrapped the same way.

Lines of literal

XML element: n:lines-of-literal, n:raw-lines

Three lower-than signs <<< and three greater-than signs >>> may enclose one line of literal text or more. The angled brackets delimiting the paragraphs take place on the first column of the line, and there must be no other character on the same line.

The literal text may contain any character, including escaped characters and greater-than signs, as long as they don’t form an ending delimiter (if you need to display that, then use an escaped character).

With Novelang default stylesheet, such text will be rendered verbatim, with a fixed-width font:

<<<
Here is literal.
  Indentation will be kept.
>>>

The n:raw-lines element appears wrapped inside the n:lines-of-literal element. Such an enclosed element is useful as a placeholder for tags.

Word after circumflex accent

XML element: n:word-after-circumflex-accent

A circumflex accent ^ may introduce a word immediately following another word.

With Novelang default stylesheet, the second word is is displayed as superscript:

April, the 1^st.

URL

XML elements: n:url, n:url-literal

A URL is primarily made of URL literal, which starts at the first column of a line, with nothing else on the same line (except trailing whitespaces).

When the URL literal is preceded by a block inside double quotes, or a block inside square brackets, it becomes a child of the n:url element.

With Novelang default stylesheet, the external link will show as a hyperlink named “here”:

So you can click "here"
http://novelang.sourceforge.net
.

If the block inside double quotes, or the block inside square brackets must appear verbatim, then break the relationship by inserting some text element which won’t affect rendering.

No "name" ` `
http://novelang.sourceforge.net

Tables

XML elements: n:cell-rows-with-vertical-line, n:cell-row, n:cell

A pair of vertical lines delimits a “cell”, which contains words, punctuation signs and various blocks, but no line break. The first vertical line must appear on the first column.

Several cells can be chained on the same line, using one additional vertical bar each time, thus forming a cell row.

One cell row, or a sequence of cell rows separated by line breaks, appear wrapped in a n:cell-rows-with-vertical-line element.

With Novelang default stylesheet, such a sequence of cell rows is arranged as a table:

| row1, col1 | row1, col2  | row1, col3 |
| row2, col1 |  row2, col2 | row2, col3 |

Tables behave like paragraphs in the sense they must be separated of other paragraph-like stuff by a pair of line breaks.

Raster images

XML elements: n:raster-image, n:resource-location, n:image-width, n:image-height

Raster images are also known as “bitmap” images, which are made of a grid of pixels.

The file path of an image represents the image to appear in the document. It may only appear as a paragraph (two line breaks separating from other paragraphs), or inside a table cell.

The image must be in JPEG, PNG or GIF format, with the extension being one of .jpg, .png, .gif respectively.

./orchid.jpg

./flowers/tulip.png

../animals/guinea-pig.jpg

| /images/logo.gif |

The path must start with zero, one, or two full stops, immediately followed by a solidus. Then follow optional directories, and the file name itself with its extension.

  • If the image file is in the same directory as source document, then its name must start with a full stop and a solidus ./
  • Parent directories are referenced through double full stops then solidus ../
  • The project directory is considered as the root directory. Attempting to reference a directory above the project directory will produce an error. A path relative to the project directory (instead of being relative to the source document) starts with a solidus.

With Novelang default stylesheet, the image appears inside the document.

Under the n:raster-image element, the n:resource-location gives the image path relative to the project root. The n:image-width and n:image-height elements give the with and the height of the image, respectively, in pixel units.

Vector images

XML elements: n:raster-image, n:resource-location

Vector images work the same way as raster images. The image must be in SVG 1. 1 format, with .svg as extension.

./stars.svg

The with or the height of the vector image is copied from the SVG file, including units. Coordinates and lengths in SVG are explained here.

SVG documents may reference an external entity with a public identifier like -//W3C//DTD SVG 1.1" or -//W3C//ENTITIES SVG 1.1 or -//W3C//ELEMENTS SVG 1.1. Other external entities are not supported yet.

Tags

XML elements: n:explicit-tag, n:promoted-tag, n:implicit-tag

A tag is a textual marker attached to some piece of a source document. It is made of a commercial at @, immediately followed by letters, digts, and hyphen minus (hyphen minus may only appear between letters and digits and there cannot be two consecutive ones). The tag appears immediately before tagged content (no more than one line break separating them).

By now, following Novelang constructs support tags:

  • Level.
  • Paragraph.
  • Paragraph as list item.
  • Paragraphs inside angled bracket pairs.
  • Cell rows with vertical line.

A tag is not meant to be content by itself, but it may help to categorize the content, or provide additional information to the stylesheet.

Tags are passed as parameters to the HTTP dæmon or the batch generator, with the tags argument name, and with a semicolon as delimiter:

my-document.html?tags=TAG-1;TAG-2

With Novelang default stylesheet for HTML, the tags are rendered as tiny colorful floating rectangles in the right margin. A list of available tags appears in the topright corner in a disclosure blox. Checking / unchecking tags causes the document to display only tagged text, by requesting a document with the new URL.

Default stylesheet for PDF doesn’t render tags in a particular manner. But, as expected, if some text is excluded because it has none of requested tags, it will be excluded from rendition.

Tag usage sample:

  @my-tag @Level
== Tagged level

  @my-tag @some-other-tag
My tagged paragraph.

== Level: no explicit tag

The XML structure of source document above looks like this:

+ n:novella
  + n:level
    + n:explicit-tag "my-tag"
    + n:explicit-tag "Level"
    + n:level-title "Tagged level"
    + n:regular-paragraph
      + n:-explicit-tag "my-tag"
      + n:explicit-tag "some-other-tag"
      + "My tagged paragraph."
  + n:level
    + n:promoted-tag "Level"
    + n:implicit-tag "noExplicitTag"
    + n:level-title "Level: no explicit tag"

Level titles may also convert to Implicit Tags or Promoted Tags. Implicit Tags don’t appear in the Tag list, but filtering on a given Tag retains document fragments tagged with Implicit Tags.

Implicit Tags come out from level title from a few simple transformation rules.

  • Convert every letter to its form without diacritics.
  • Whitespaces disappear.
  • Punctuation signs and delimiters disappear. They become Tag boundaries.
  • The first letter of a word that was preceded by another words gets uppercased.

Promoted Tags are Implicit Tags that match some Explicit Tag defined elsewhere in the document.

Here are a few transformation samples for Implicit (and Promoted) Tags:

Original Novelang sourceImplicit Tags
This is some text. Be cool.@BeCool @ThisIsSomeText
This is a title... (So what?)@ThisIsATitle @SoWhat
version `0.1.2.3`@version0-1-2-3
Some ``@#!garbage)<--.§``here!@Some-garbage-Here

Identifiers

XML element: n:implicit-identifier, n:explicit-identifier, n:colliding-explicit-identifier

An identifier is a textual marker identifying a level inside a Novella. The insert command (explained in “Opus syntax” chapter) recognizes identifiers to insert only given levels. An identifier starts with a double reverse solidus \\. The rest of the identifier is made of letters, digts, and hyphen minus (hyphen minus may only appear between letters and digits and there cannot be two consecutive ones).

Because often, titles are good candidates for identifiers, they resolve implicitely as identifiers as long as they are unique. As a result of Novella processing, an identifier may be either explicit or implicit. All implicit identifiers resolve as absolute ones.

Given following Novella file:

Paragraph 0

  \\One
== Level 1


  \\One-one
=== Level 1.1

Paragraph 1.1


=== Other

Other level (2)


=== Level 1.2

Paragraph 1.2

==== Level 1.2.1

Paragraph 1.2.1

==== Other

Other level (2)

It has:

  • 2 explicit identifiers:
    • \\One
    • \\One-onz
  • 3 implicit identifers:
    • \\Level-1_2
    • \\Level-1_2_1

Implicit identifiers do exist as long as they don’t collide with another identifier. That’s why Other doesn’t appear as an implicit identifier.

Novelang checks uniqueness of explicit identifiers within the same Novella. Since Novellæ are created independantly, identifiers may collide when aggregating Novellæ into a single Opus. With Novelang default HTML stylsheet, colliding identifiers show striked out.

Escaped characters

For displaying character that have a special meaning in the rendered documents, they must be escaped. An escaped character is enclosed into a left-pointing double angle quotation mark « and a right-pointing double angled quotation mark ». The escape code is the unicode name. HTML entity name is supported as well.

All characters that may appear in a source document are listed in an appendix, along with their escape codes.

Using those characters is exceptional, however – except in Novelang documentation! – as most of useful character are accessible as literal.

Comments

Sometimes it is useful to tell Novelang to ignore some lines in a Novella files.

Line comments begin with double percent sign %%.

Blocks comments are delimited by a pair of double accolades {{ and }}.

%% This line is commented.

{{ These two lines are
commented. }}